/**
 *   This file is part of Java Simple Sampler.
 *
 *   Java Simple Sampler is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License.
 *
 *   Java Simple Sampler is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with Java Simple Sampler.  If not, see <http://www.gnu.org/licenses/>.
 *
 *   @author David Lapetina	
 */

package net.onirik.mao.sampler.gui;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiUnavailableException;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

import net.onirik.mao.sampler.midi.JSSMidiReceiver;
import net.onirik.mao.sampler.midi.MidiHelper;
import net.onirik.mao.sampler.sound.SamplePlayer;
import net.onirik.mao.sampler.sound.WavSamplePlayer;

public class JSSGui implements ActionListener {
	private final JFrame mainWindow;

	private JMenuBar menuBar;

	private JMenu fileMenu;

	private JMenuItem exitMenuItem;

	private Locale currentLocale = new Locale("en");

	private static final String bundle = "net/onirik/mao/sampler/gui/gui";

	private final JSSMidiReceiver receiver;

	public JSSGui() throws Exception {
		this.mainWindow = new JFrame();
		this.menuBar = new JMenuBar();
		this.fileMenu = new JMenu();
		this.exitMenuItem = new JMenuItem();
		this.fileMenu.add(this.exitMenuItem);
		this.menuBar.add(this.fileMenu);
		this.mainWindow.setJMenuBar(this.menuBar);
		this.exitMenuItem.addActionListener(this);
		this.initLabels();
		this.receiver = getMidiReceiver();
		this.mainWindow.setLayout(new GridLayout(2, 8));
		for (int i = 0; i < 16; i++)
			this.mainWindow.add(addJTable(i));
		this.mainWindow.setSize(800, 600);

		this.mainWindow.setResizable(false);
		this.mainWindow.setVisible(true);
	}

	private JScrollPane addJTable(final int channel) {
		TableModel dataModel = new JSSTableDataModel(channel, this.receiver);
		final JTable table = new JTable(dataModel);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.getSelectionModel().addListSelectionListener(
				new ListSelectionListener() {

					public void valueChanged(ListSelectionEvent e) {
						if (e.getValueIsAdjusting())
							return;
						int row = table.getSelectedRow();
						SamplePlayer player = receiver.getSamplePlayerMap(
								channel).getSamplePlayer(row, false);
						JFileChooser fileChooser = null;
						if (player != null)
							fileChooser = new JFileChooser(player
									.getResourcePath());
						else
							fileChooser = new JFileChooser();
						switch (fileChooser.showOpenDialog(mainWindow)) {
						case JFileChooser.ABORT:
							break;
						case JFileChooser.APPROVE_OPTION:
							WavSamplePlayer wavSamplePlayer = new WavSamplePlayer(
									fileChooser.getSelectedFile()
											.getAbsolutePath());
							// -2 ... see JSSTableDataModel.getValue();
							receiver.getSamplePlayerMap(channel)
									.addSamplePlayer(row - 2, wavSamplePlayer);
							// refresh cell
							table.repaint();
							break;
						}
					}

				});
		return new JScrollPane(table);
	}

	//TODO parameters ... in configuration file !
	public JSSMidiReceiver getMidiReceiver() throws MidiUnavailableException, InvalidMidiDataException {
		// under linux you may need a modprobe snd-virmidi before starting
		// application.
		// other midi devices do not seem to be seen.
		List devices = MidiHelper.listDevices("VirMIDI");
		// should have only one, change the name you'd like above.
		MidiHelper helper = MidiHelper.getMidiHelper((MidiDevice.Info) devices
				.get(0));
		JSSMidiReceiver receiver = new JSSMidiReceiver();
		// for now add error.wav as default on channel 1 (i.e. 0 since in java
		// we start counting at 0).
		//receiver.getSamplePlayerMap(0).setDefaultPlayer(
		//		new WavSamplePlayer("sounds/error.wav"));
		receiver.getSamplePlayerMap(0).addSamplePlayer(0,
				new WavSamplePlayer("sounds/pianonote.wav"));
		
		// for now add info.wav as default on channel 2 (i.e. 1 since in java we
		// start counting at 0).
		receiver.getSamplePlayerMap(1).setDefaultPlayer(
				new WavSamplePlayer("sounds/info.wav"));
		helper.registerReceiver(receiver);
		helper.open();
		return receiver;
	}

	public void initLabels() {
		ResourceBundle resourceBundle = ResourceBundle.getBundle(bundle,
				currentLocale);
		this.mainWindow.setTitle(resourceBundle.getString("title"));
		this.fileMenu.setText(resourceBundle.getString("menu.file"));
		this.exitMenuItem.setText(resourceBundle.getString("menu.exit"));
	}

	public void actionPerformed(ActionEvent action) {
		if (action.getSource().equals(this.exitMenuItem))
			System.exit(0);
		//System.out.println(action);
	}

	public static void main(String[] a) throws Exception {
		JSSGui gui = new JSSGui();
	}
}
